package com.ian.homework;

import java.util.Scanner;

/**
 * 控制台五子棋
 */
public class Gobang {
    private boolean isGameOver = false;
    //15*15棋盘
    private char[][] baArrayTable = new char[16][16];
    //两个玩家
    private GobangPlayer objPlay1, objPlay2;
    //回合
    private int iRound = 0;


    public void createGame(GobangPlayer p1, GobangPlayer p2) {
        this.objPlay1 = p1;
        this.objPlay2 = p2;
    }

    /**
     * 展示棋局
     **/
    private void show() {
        int iIndex = 0;
        char cChar[] = new char[]{'a', 'b', 'c', 'd', 'e', 'f'};
        System.out.println("    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f ");
        for (char[] cs : baArrayTable) {
            // System.out.print(" "+iIndex+(iIndex>9?"":" ")+" ");
            if (iIndex < 10) {
                System.out.print(" " + iIndex + (iIndex > 9 ? "" : " ") + " ");
            } else {
                System.out.print(" " + cChar[iIndex - 10] + " ");
            }
            for (char c : cs) {
                if (c == 0) System.out.print("+");
                System.out.print(c + " ");
            }
            System.out.println();
            iIndex++;
        }
    }

    /**
     * 获取下一个走棋的
     **/
    private GobangPlayer getPlayer() {
        //黑子先走
        if (iRound == 0) return objPlay1.getColor() == '黑' ? objPlay1 : objPlay2;
        //根据回合判断棋子颜色
        if (iRound % 2 != 0) return objPlay1.getColor() == '白' ? objPlay1 : objPlay2;
        return objPlay1.getColor() == '黑' ? objPlay1 : objPlay2;
    }

    /**
     * 判断是否获胜
     **/
    private boolean isWin(int x, int y, char c) {
        /*
         *  7 8 9
         *  4 5 6
         *  1 2 3
         */
        int iIndexX = 0, iIndexY = 0;
        for (int i = 1; i < 9; i++) {
            switch (i) {
                case 1:
                    iIndexX = -1;
                    iIndexY = -1;
                    break;
                case 2:
                    iIndexX = -1;
                    iIndexY = 1;
                    break;
                case 3:
                    iIndexX = 1;
                    iIndexY = -1;
                    break;
                case 4:
                    iIndexX = 1;
                    iIndexY = 1;
                    break;
                case 5:
                    iIndexX = 0;
                    iIndexY = 1;
                    break;
                case 6:
                    iIndexX = 1;
                    iIndexY = 0;
                    break;
                case 7:
                    iIndexX = 0;
                    iIndexY = -1;
                    break;
                case 8:
                    iIndexX = -1;
                    iIndexY = 0;
                    break;
            }

            if ((x < 4 && iIndexX == -1) || (y < 4 && iIndexY == -1)) {

            } else if ((x > 12 && iIndexX == 1) || (y > 12 && iIndexY == 1)) {

            } else if (x < 4 && y < 4 && (iIndexX != -1 && iIndexY != -1)) {
                if (isHas(x, y, iIndexX, iIndexY, 4, c))
                    return true;
            } else if (x > 12 && y > 12 && (iIndexX != 1 && iIndexY != 1)) {
                if (isHas(x, y, iIndexX, iIndexY, 4, c))
                    return true;
            } else if (iIndexX == 0 || iIndexY == 0) {
                if (isHas(x, y, iIndexX, iIndexY, 4, c))
                    return true;
            }
            if (x > 2 && y > 2 && x < 14 && y < 14) {
                if (isHas(x, y, iIndexX, iIndexY, 2, c) && isHas(x, y, -iIndexX, -iIndexY, 2, c)) {
                    return true;
                }
            }

            if (x > 3 && y > 3 && x < 15 && y < 15) {
                if (isHas(x, y, iIndexX, iIndexY, 3, c) && isHas(x, y, -iIndexX, -iIndexY, 1, c)) {
                    return true;
                }
            }
            if (x > 1 && y > 1 && x < 13 && y < 13) {
                if (isHas(x, y, iIndexX, iIndexY, 1, c) && isHas(x, y, -iIndexX, -iIndexY, 3, c)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检测是否有棋子
     *
     * @param x       x坐标
     * @param y       y坐标
     * @param iIndexX x方向
     * @param iIndexY y方向
     * @param iNum    缓存
     * @return
     */
    private boolean isHas(int x, int y, int iIndexX, int iIndexY, int iNum, char c) {
        if (iNum == 1) {
            if (baArrayTable[x + iIndexX][y + iIndexY] == c) return true;
        } else if (baArrayTable[x + iIndexX][y + iIndexY] == c) {
            return isHas(x + iIndexX, y + iIndexY, iIndexX, iIndexY, iNum - 1, c);
        }
        return false;
    }

    /**
     * 下棋
     **/
    public boolean put(int x, int y, GobangPlayer p) {
        if (baArrayTable[x][y] == 0) {
            baArrayTable[x][y] = p.getColor();

            if (isWin(x, y, p.getColor())) {
                isGameOver = true;
                System.out.println(p.getUsername() + "(" + p.getColor() + ")赢得了胜利");
            }
            return true;
        }
        return false;
    }

    /**
     * 游戏运行
     **/
    public void start() {
        GobangPlayer p = null;
        Scanner scan = new Scanner(System.in);
        String[] strArr = new String[2];
        while (!isGameOver) {
            if (p == null) p = getPlayer();
            System.out.println("第" + (iRound / 2 + 1) + "回合,下子方：" + p.getUsername() + "(" + p.getColor() + ")");
            System.out.println("请输入你要下的位置（空格隔开） 例如 10 5");
            //下棋失败重新开始本回合
            try {
                String in = scan.nextLine().trim();
                if ("exit".equals(in)) break;
                strArr = in.split(" ");
                int iIndexX = Integer.parseInt(strArr[0]);
                int iIndexY = Integer.parseInt(strArr[1]);
                //越界检测
                if (iIndexX > 15 || iIndexY > 15) {
                    System.out.println("棋子越界");
                    continue;
                }
                if (!put(iIndexX, iIndexY, p)) continue;
            } catch (Exception e) {
                e.printStackTrace();
            }
            show();
            p = null;
            iRound++;
        }
        System.out.println("游戏结束");

    }

}
